﻿#include <gtest/gtest.h>

#include "algo/algo_ode_solver.h"

#include <dbg.h>

using namespace CAGD;

#define EXP 2.718281828

double lambda = -100;
double eta = 1.5;
// double k = 0.01;
// double T = 1;

// // 需要注意 N = T / k 的计算方法可能不准
// int N = 100;

// 应该这样计算
double T = 1;
int N = 1000;
double k = T / N;

Vector f(Vector x, double t)
{
    return Vector(1, lambda * (x[0] - cos(t)) - sin(t));
}

double u(double t)
{
    return pow(EXP, lambda * t) * (eta - 1) + cos(t);
}

TEST(TestODE, RungeKutta)
{
    ODESolver solver;

    {
        ClassicalRK method(k);

        // 注意要多给一个
        TimeGrid G(N + 1, Vector(1));
        G[0] = {eta};
        solver(f, G, &method);
        EXPECT_TRUE(fabs(G.back()[0] - u(T)) < 1e-6);
    }

    {
        ESDIRK method(k);
        TimeGrid G(N + 1, Vector(1));
        G[0] = {eta};
        solver(f, G, &method);
        EXPECT_TRUE(fabs(G.back()[0] - u(T)) < 1e-6);
    }

    {
        GaussLegendreRK method(3, k);
        TimeGrid G(N + 1, Vector(1));
        G[0] = {eta};
        solver(f, G, &method);
        EXPECT_TRUE(fabs(G.back()[0] - u(T)) < 1e-6);
    }
}